<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"
    />
    <meta name="author" content="林镭特" />
    <title></title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <style>
      * {
        box-sizing: border-box;
      }
      .slider-box {
        display: inline-block;
        width: 100px;
        height: 10px;
        background-color: lightblue;
        border-radius: 5px;
        cursor: pointer;
        position: relative;
      }
      .slider-progress {
        width: 20px;
        height: 10px;
        background-color: plum;
        border-radius: 5px;
      }
      .slider-ball {
        width: 20px;
        height: 20px;
        border-radius: 50%;
        background-color: black;
        position: absolute;
        left: 10px;
        top: -5px;
      }
    </style>
  </head>
  <body>
    <div id="app">
      <div v-if="width!=100">
        {{progress*2}}
      </div>
      <div v-else>
        {{progress}}
      </div>

      <br />
      <div>设置宽度 <input type="number" v-model.number="width" /></div>
      <div>值上限 <input type="number" v-model.number="max" /></div>
      <div>值下限 <input type="number" v-model.number="min" /></div>
      <my-slider
        :width="width"
        :max="max"
        :min="min"
        v-model="progress"
      ></my-slider>
    </div>

    <script id="my-slider" type="text/html">
      <!-- 边框 -->
      <div class="slider-box" :style="boxStyle" @mousedown="sliderDown" @mousemove="sliderMove">
          <!-- 进度的显示 -->
          <div class="slider-progress" :style="progressStyle"></div>
          <!-- 滑块 -->
          <div class="slider-ball" :style="ballStyle"></div>
      </div>
    </script>

    <script>
      Vue.component("my-slider", {
        template: "#my-slider",
        props: {
          value: {
            type: Number,
            default: 0,
          },
          // slider的宽度
          width: {
            type: Number,
            default: 100,
            validator(v) {
              return v > 0;
            },
          },
          max: {
            type: Number,
            default: 100,
          },
          min: {
            type: Number,
            default: 0,
          },
        },
        data() {
          return {
            isMoving: false,
          };
        },
        computed: {
          boxStyle() {
            return {
              width: this.width + "px",
            };
          },
          offsetWidth() {
            let offset = (this.value * this.width) / 100;
            console.log(offset);
            offset = Math.min(offset, this.max);
            offset = Math.max(offset, this.min);
            console.log(offset);
            return offset;
          },
          progressStyle() {
            return {
              width: this.offsetWidth + "px",
            };
          },
          ballStyle() {
            return {
              left: this.offsetWidth - 10 + "px",
            };
          },
        },
        methods: {
          sliderDown(ev) {
            this.isMoving = true;
            this.move(ev);
          },
          seliderUp() {
            this.isMoving = false;
          },
          sliderMove(ev) {
            if (this.isMoving) {
              this.move(ev);
            }
          },
          move(ev) {
            let distance = ev.pageX - this.$el.getBoundingClientRect().left;
            // console.log("distance1  "+distance);
            distance = Math.min(distance, this.max);
            distance = Math.max(distance, this.min);
            // console.log("distance2  "+distance);
            // console.log("width  "+this.width);
            let rate = distance / (this.width / 100);
            // console.log(rate);

            this.$emit("input", rate);
          },
        },
        created() {
          document.addEventListener("mouseup", this.seliderUp);
        },
      });

      let app = new Vue({
        el: "#app",
        data: {
          progress: 0,
          width: 100,
          max: 100,
          min: 0,
        },
      });
    </script>
  </body>
</html>
